//自定义监控模块
let Module = function(opts){
    console.log("online modules constructor");
    opts = opts||{};
    //当前监控模块所监测的服务器实例
    this.app = opts.app;
    //获取数据的方式
    // pomelo-admin提供两种方式一种是pull拉取，一种是push推送
    // pull拉取表示master服务器会主动从各个游戏服务器上拉取所需的监控数据
    // push推送表示游戏服务器向master服务器推送监控数据
    this.type = opts.type || "pull";
    //每次push或pull的时间间隔
    this.interval = opts.interval || 5;
};

// 监控模块标识
// 用于唯一标识监控模块，非常重要。
// 如果要向该模块获取和发送数据都需要依靠这个ID作为参数
// 如果需要让外部程序获取该模块的监控数据也必须依靠此参数
Module.moduleId = "online";

// 采用pull拉取 当接收到master主服务器拉通知时回调
// 采用push推送 每次到达interval间隔时间时回调
Module.prototype.monitorHandler = function(agent, msg){
    console.log("online modules handler");
    //获取连接组件服务
    const connectionService = this.app.components.__connection__;
    if(!connectionService){
        console.log("not support connection: %j", agent.id);
        return;
    }
    //代理通知连接统计信息
    const info = connectionService.getStatisticsInfo();
    //通知admin的消息给master服务器
    agent.notify(Module.moduleId, info);
};

// 采用pull拉取 每次到达pull拉取时间间隔时会被调用
// 采用push推送 当接收到游戏服务器push推送数据回调
Module.prototype.masterHandler = function(agent, msg){
    console.log("online master handler", msg, Module.moduleId);
    //若无消息则通知所有的monitor监视器去获取数据
    if(!msg){
        //通知指定类型的监听器获取获取数据
        const type = "connector";
        const list = agent.typeMap[type];
        if(!list || list.length===0){
            agent.notifyByType(type, Module.moduleId);
        }else{
            //通知所有监视器去获取数据
            agent.notifyAll(Module.moduleId);
        }
        return;
    }
    //从monitor监视器中收集数据
    let data = agent.get(Module.moduleId);
    if(!data){
        data = {};
        agent.set(Module.moduleId, data);
    }
    data[msg.serverId] = msg;
};

//当第三方程序调用时 获取监控数据接口时回调
Module.prototype.clientHandler = function(agent, msg, cb){
    console.log("online client handler");
    if(!!cb && typeof cb==="function"){
        const param = agent.get(Module.moduleId) || {};
        //处理客户端请求直接返回数据并缓存到master服务器
        cb(null, param);
    }
};

//导出模块
module.exports.moduleId = Module.moduleId;
module.exports = function(opts){
    return new Module(opts);
};
